<?php

namespace app\utils;

use app\exception\ApiException;
use Firebase\JWT\Key;
use app\utils\ApiErrorCode;
use support\Redis;

class Jwt
{
    /**
     * token
     * @var string
     */
    protected $token;

    /**
     * @var string
     */
    protected $app_key = 'webman';


    public function getToken(int $id, string $type, array $params = []): array
    {
        $host = request()->host();
        $time = time();
        $exp_time = strtotime('+ 7day');

        $params += [
            'iss' => $host,
            'aud' => $host,
            'iat' => $time,
            'nbf' => $time,
            'exp' => $exp_time,
        ];
        $params['jti'] = compact('id', 'type');
        $token = \Firebase\JWT\JWT::encode($params, config('jwt.secret_key'), 'HS256');
        return compact('token', 'params');
    }

    public function parseToken(string $jwt): array
    {
        $this->token = $jwt;
        [$headb64, $bodyb64, $cryptob64] = explode('.', $this->token);
        $payload = \Firebase\JWT\JWT::jsonDecode(\Firebase\JWT\JWT::urlsafeB64Decode($bodyb64));
        return [$payload->jti->id, $payload->jti->type, $payload->auth ?? ''];
    }


    public function verifyToken()
    {
        \Firebase\JWT\JWT::$leeway = 60;
        \Firebase\JWT\JWT::decode($this->token, new Key(config('jwt.secret_key'), 'HS256'));
        $this->token = null;
    }

    public function createToken(int $id, string $type, array $params = [])
    {
        $tokenInfo = $this->getToken($id, $type, $params);
        $exp = $tokenInfo['params']['exp'] - $tokenInfo['params']['iat'] + 60;
        $data = [
            'user_id' => $id,
            'type'    => $type,
            'token'   => $tokenInfo['token'],
            'exp'     => $exp,
        ];
//        $res = CacheService::setTokenBucket(md5($tokenInfo['token']), $data, (int)$exp, $type);
        $res = Redis::set(key: md5($tokenInfo['token']), value: json_encode($data), expireTTL: (int)$exp);
        if (!$res) {
            throw new ApiException(ApiErrorCode::ERR_SAVE_TOKEN);
        }
        return $tokenInfo;
    }
}
